FreeRTOS 中断与临界区问答合集

📖 精选 📅 2026-09-04
#来源/立芯星球 #类型/问答合集 #技术/FreeRTOS #技术/中断

FreeRTOS 中断与临界区问答合集

由 14 篇星球问答重组而成,覆盖中断优先级分段、临界区保护、SVC/PendSV、SysTick 时基与 HAL_Delay 坑四大主题。原帖全部保留,见文末来源清单。

一、中断优先级分段(最核心的一组概念)

ARM 中断优先级只有 0~15(4 位)是芯片架构决定的吗?
不是。ARM 的中断优先级配置位可以不止 4 位,是芯片厂商(如 ST)只实现了 4 位。FreeRTOS 移植后进入 PendSV 就开始任务切换,这与 CPU/厂商(NXP、ST 等)无关。另外 FreeRTOS 用 SysTick 做时基,HAL 库需要自己独立的另一个定时器做时基。
1、Arm架构的中断优先级 正常配置 最大值就是15 这个是由芯片架构决定(Jack)

为什么中断优先级要设成"5 以上"(数字更大)才能被 FreeRTOS 管理?
STM32 中断优先级数字越小优先级越高。FreeRTOS 默认把 5~15 段划为可管理段;优先级数字小于 5(优先级更高)的中断里无法调用 FreeRTOS 的 API。反过来说,把按键 EXTI 设为 5(数值可调),才能在中断回调里调用队列发送等 FromISR 函数;设成 0~4 就不能调用。
如果这个中断的优先级小于五,那(iiikkkiii)
同题变体:— 想问问这个EXITI line0为什么设置为5,就是FreeRTOS可屏蔽中断(Jack)

进入临界区期间,还能触发硬件中断吗?
能。FreeRTOS 存在"不可屏蔽段"(即上面优先级 0~4 的中断),它们不受临界区屏蔽,随时可以打断 taskENTER_CRITICAL 保护下的代码——这也是"5 以上才可管理"的另一面。
请问,进入临界区期间,能触发硬(Jack)

二、临界区与互斥

临界区和互斥锁效果一样吗?什么时候用哪个?
不一样:互斥锁用于保护变量不在使用中被(其他任务)更新——任务是"平级"的互斥;临界区用于执行时序敏感代码段时确保不被中断干扰。
老师们,想不通,临界区和互斥锁是一样的效果么?什么时候用临界区 什么时候用互斥锁(Jack)

taskENTER_CRITICAL 嵌套调用,uxCriticalNesting 会不会卡住退不出来?
不会。已经调用 taskENTER_CRITICAL 之后,任务切换根本不可能发生——任务切换必须在 PendSV 中断中进行,而临界区内相应中断被屏蔽,所以嵌套计数总能成对递减。
taskENTER_CRITICA里会将uxCriticalNesting++(Jack)

中断里为什么不能进行任务调度?
任务切换依赖 PendSV,且要等所有中断退出后才发生;中断里只应做置标志、发信号量(FromISR)等轻量动作,直接在中断中调度会破坏这套机制。
中断中不要进行任务调度(Jack)

裸机(没有互斥锁)下,while 和中断都会改的全局变量怎么保护?
给这个变量做一个访问接口,访问前关闭全局中断——相当于自己实现了一把锁,确保临界问题不发生。(之前 uint8_t"修改不成功"就是典型的读-改-写竞态。)
你需要把这个变量做一个访问的接(Jack)

三、SVC 与 PendSV

FreeRTOS 第一次启动用 SVC,之后都用 PendSV,两者有什么不一样?
SVC 是一条指令,会产生 SVC 中断悬起,其优先级很高,CPU 立刻响应;在 SVC 服务函数里可以去置位 PendSV 的悬起,而 PendSV 优先级最低,往往等所有中断都退出后才进入 PendSV 服务函数完成任务切换——这就是 "pending" 的含义。可以把 SVC 理解为"进入内核态去置位某些中断"。
老师,我看freertos pendsv中断和svc中断都用了。第一次用svc(Jack)
机制补充:— svc是个指令,会产生svc中断悬起,svc的中断优先级很高(Jack)

四、SysTick 时基与 HAL_Delay 的坑

为什么 FreeRTOS 时基用 SysTick,HAL 时基却要换一个定时器?
HAL 库需要自己的时基计数。若两者共用 SysTick,FreeRTOS 接管后 HAL 的 tick 不再正常递增,HAL_Delay 就会出问题——所以 CubeMX 配置 FreeRTOS 时会把 HAL 时基挪到另一个普通定时器。
为什么Freertos时基用systick,然后HAL的时基要用另一个定时器(Jack)

HAL_Delay(100) 和 osDelay(100) 有什么区别?
HAL_Delay 是 HAL 库的延时,靠查询 HAL 时基(无 RTOS 时即 SysTick 计数)忙等;osDelay 是 FreeRTOS 的延时,调用后当前任务进入阻塞并触发任务切换,CPU 去运行其他任务。
HAL_Delay(100);(Jack)

systick 优先级最低,为什么调用 HAL_Delay 会卡死?
systick 优先级最低,任意外部中断都比它高;执行中断服务函数期间 systick 无法 tick++,而 HAL_Delay 等的恰恰是 tick 变化——tick 不动,程序就永远卡在 HAL_Delay 里。典型场景:CubeMX 只配 FreeRTOS 的裸工程一调 HAL_Delay 就卡死,补上 HAL_IncTick 调用后才恢复,就是同一机理。
老师,还是有点没搞懂,systick优先级低于中断(Jack)
场景原帖:— 我用cubemx配了一个只带freertos没有配置其他外设的工程(圣井户御代)

来源笔记